﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using RestSharp;

namespace INdTFramework.Controls
{
    /// <summary>
    /// The ImageCache is a kind of Image control that allow the client application
    /// display a placeholder image, while loading the real image from remote servers
    /// on web. This when the application is working under slow connection to avoid
    /// a "empty" space while it is downloading the desired image.
    /// </summary>
    public partial class ImageCache : UserControl
    {
        private bool loaded;

        static DependencyProperty TemporaryImageProperty = DependencyProperty.Register("TemporaryImage", typeof(ImageSource), typeof(ImageCache), new PropertyMetadata(TemporaryImageChanged));
        static DependencyProperty HolderImageProperty = DependencyProperty.Register("HolderImage", typeof(ImageSource), typeof(ImageCache), new PropertyMetadata(null));
        static DependencyProperty ImageStrechProperty = DependencyProperty.Register("ImageStretch", typeof(Stretch), typeof(ImageCache), new PropertyMetadata(ImageStretchChanged));

        public Stretch ImageStretch
        {
            get
            {
                return ((Stretch)GetValue(ImageStrechProperty));
            }
            set
            {
                SetValue(ImageStrechProperty, value);
            }
        }

        public ImageSource HolderImage
        {
            get
            {
                return GetValue(HolderImageProperty) as ImageSource;
            }

            set
            {
                SetValue(HolderImageProperty, value);
                CheckTemporaryImage();
            }
        }

        public ImageSource TemporaryImage
        {
            get
            {
                return GetValue(TemporaryImageProperty) as ImageSource;
            }

            set
            {
                SetValue(TemporaryImageProperty, value);
                CheckHolderImage();                
            }
        }


        static void TemporaryImageChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var control = dependencyObject as ImageCache;

            if (control != null)
            {
                control.Holder.Source = dependencyPropertyChangedEventArgs.NewValue as ImageSource;
            }
        }

        static void ImageStretchChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var control = dependencyObject as ImageCache;

            if (control != null)
            {
                control.Holder.Stretch = ((Stretch)dependencyPropertyChangedEventArgs.NewValue);
            }
        }
        
        public ImageCache()
        {
            InitializeComponent();
        }

        private void ImageCacheLoaded(object sender, RoutedEventArgs e)
        {
            if (!loaded && TemporaryImage != null && HolderImage != null)
            {
                DownloadImage();
            }
        }

        void CheckTemporaryImage()
        {
            if (TemporaryImage != null)
            {
                DownloadImage();
            }
        }

        void CheckHolderImage()
        {
            if (HolderImage != null)
            {
                DownloadImage();
            }
        }

        void DownloadImage()
        {
            loaded = true;
            ProgressDownload.Visibility = Visibility.Visible;
            Holder.Source = TemporaryImage;

            var url = (HolderImage as BitmapImage).UriSource.AbsoluteUri;

            Get(url, SetHolderImage);
        }

        void SetHolderImage(IRestResponse response)
        {
            if (response.ErrorException == null && response.StatusCode.Equals(HttpStatusCode.OK))
            {
                Holder.Source = HolderImage;
            }

            ProgressDownload.Visibility = Visibility.Collapsed;
        }

        void Get(string url, Action<IRestResponse> action)
        {
            var restClient = new RestClient { BaseUrl = url };
            var request = new RestRequest { Method = Method.GET };

            restClient.ExecuteAsync(request, action);
        }
    }
}
